﻿#region

using System;

using Microsoft.Xna.Framework;

using Pob.CustomEventArgs;
using Pob.ScreenManagement;
using Pob.ScreenManagement.GameScreens;
using Pob.ScreenManagement.OptionsScreens;

#endregion

namespace Pob
{
    public class GameManagement : Game
    {
        #region Fields

        private readonly GraphicsDeviceManager _graphics;

        private readonly Settings _settings;

        private ScreenManager _screenManager;

        #endregion

        #region Constructors and Destructors

        public GameManagement()
        {
            if (!SettingsManager.CurrentInstance.Load())
            {
                SettingsManager.CurrentInstance.SetDefaultValues();
            }

            _settings = SettingsManager.CurrentInstance.Settings;

            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            _graphics.PreferredBackBufferWidth = _settings.Width;
            _graphics.PreferredBackBufferHeight = _settings.Height;
        }

        #endregion

        #region Methods

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            base.Draw(gameTime);
        }

        protected override void Initialize()
        {
            _screenManager = new ScreenManager(this);
            _screenManager.Add(new BackgroundScreen(this, "background"));
            _screenManager.Add(new MainMenuScreen(this, MenuEvent));

            Components.Add(_screenManager);
            base.Initialize();
        }

        protected override void OnExiting(object sender, EventArgs args)
        {
            SettingsManager.CurrentInstance.Save();
            base.OnExiting(sender, args);
        }

        private void GameScreenEvent(object obj, GameScreenEventArgs args)
        {
            var sender = (ScreenBase)obj;

            switch (args.GameState)
            {
                case GameState.Over:
                    {
                        _screenManager.Add(new ScoreScreen(this, GameScreenEvent, args.Winner), true);
                        break;
                    }

                case GameState.Paused:
                    {
                        _screenManager.Add(new PausedScreen(this, GameScreenEvent), true);
                        break;
                    }

                case GameState.Resumed:
                    {
                        _screenManager.Remove(sender, true);
                        break;
                    }

                case GameState.New:
                    {
                        _screenManager.Clear();
                        _screenManager.Add(new GameScreen(this, GameScreenEvent));
                        break;
                    }

                case GameState.Exit:
                    {
                        _screenManager.Clear();
                        _screenManager.Add(new BackgroundScreen(this, "background"));
                        _screenManager.Add(new MainMenuScreen(this, MenuEvent));
                        break;
                    }
            }
        }

        private void MenuEvent(object obj, MenuItemPickedEventArgs args)
        {
            var sender = (ScreenBase)obj;

            _screenManager.Remove(sender);

            switch (args.MenuState)
            {
                case MenuStates.Start:
                    {
                        _screenManager.Clear();
                        _screenManager.Add(new GameScreen(this, GameScreenEvent));
                        break;
                    }

                case MenuStates.Options:
                    {
                        _screenManager.Add(new OptionsScreen(this, MenuEvent));
                        break;
                    }

                case MenuStates.Exit:
                    {
                        Exit();
                        break;
                    }

                case MenuStates.PlayerOne:
                    {
                        _screenManager.Add(new PlayerOptionsScreen(this, MenuEvent, _settings.PlayerOne));
                        break;
                    }

                case MenuStates.PlayerTwo:
                    {
                        _screenManager.Add(new PlayerOptionsScreen(this, MenuEvent, _settings.PlayerTwo));
                        break;
                    }

                case MenuStates.OptionsBack:
                    {
                        _screenManager.Add(new MainMenuScreen(this, MenuEvent));
                        SettingsManager.CurrentInstance.Save();
                        break;
                    }

                case MenuStates.Rematch:
                    {
                        _screenManager.Add(new GameScreen(this, GameScreenEvent));
                        break;
                    }

                case MenuStates.Menu:
                    {
                        _screenManager.Add(new MainMenuScreen(this, MenuEvent));
                        break;
                    }

                case MenuStates.PlayerOptionsBack:
                    {
                        _screenManager.Add(new OptionsScreen(this, MenuEvent));
                        SettingsManager.CurrentInstance.Save();
                        break;
                    }
            }
        }

        #endregion
    }
}